package concept.misc;

import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedHashMap;
import java.util.Map;

import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;

public class XmlParser extends DefaultHandler
{
	private XMLReader xr;
	private Map<String, String> entries = null;
	private String localname;
	private String value;
	private boolean collecting = false;

	public XmlParser() throws SAXException
	{
		super();
		xr = XMLReaderFactory.createXMLReader();
		xr.setContentHandler(this);
		xr.setErrorHandler(this);
	}

	private void parse(InputStream source) throws SAXException, IOException
	{
		xr.parse(new InputSource(source));
	}

	public Map<String, String> getMap(InputStream source) throws SAXException, IOException
	{
		this.parse(source);

		return entries;
	}

	public void startDocument()
	{
		entries = new LinkedHashMap<String, String>();
		collecting = false;
	}

	public void startElement(String uri, String name, String qName, Attributes atts)
	{
		if (localname == null || !name.equalsIgnoreCase(localname))
		{
			localname = name;
			value = "";
			collecting = true;
		}
	}

	public void characters(char[] ch, int start, int length)
	{
		if (collecting)
		{
			for (int i = start; i < start + length; i++)
			{
				switch (ch[i])
				{
				case '\n':
				case '\r':
				case '\t':
					value += "";
					break;
				case '<':
					value += "&lt;";
					break;
				case '>':
					value += "&gt;";
					break;
				case '&':
					value += "&amp;";
					break;
				default:
					value += ch[i];
					break;
				}
			}
		}
	}

	public void endElement(String uri, String name, String qName)
	{
		if (collecting && localname.equalsIgnoreCase(name) && value != null)
		{
			entries.put(localname, value);
			localname = null;
			value = null;
			collecting = false;
		}
	}

	public void endDocument()
	{
		collecting = false;
	}
}
